"""
数据加载模块
负责从CSV文件加载数据，协调缓存管理和数据处理
"""

import pandas as pd
import os
import time


class DataLoader:
    """数据加载器"""
    
    def __init__(self, cache_manager, data_processor, data_path=None):
        """
        初始化数据加载器
        
        Args:
            cache_manager: 缓存管理器实例
            data_processor: 数据处理器实例
            data_path: 数据文件路径，默认为 'data/room_occupancy.csv'
        """
        self.cache_manager = cache_manager
        self.data_processor = data_processor
        self.data_path = data_path or os.path.join('data', 'room_occupancy.csv')
    
    def _load_csv_file(self):
        """
        从CSV文件加载原始数据
        
        Returns:
            DataFrame: 原始数据
        """
        try:
            if not os.path.exists(self.data_path):
                raise FileNotFoundError(f"数据文件不存在: {self.data_path}")
            
            print(f"从文件加载数据: {self.data_path}")
            df = pd.read_csv(self.data_path)
            
            if df.empty:
                raise ValueError("CSV文件为空")
            
            print(f"成功加载 {len(df)} 条原始记录")
            return df
            
        except Exception as e:
            print(f"加载CSV文件时出错: {e}")
            raise
    
    def preload_data(self):
        """
        预加载并处理数据，在应用启动时调用
        
        Returns:
            dict: 操作结果
        """
        try:
            print("开始预加载数据...")
            
            # 1. 加载原始数据
            raw_df = self._load_csv_file()
            
            # 2. 预处理数据
            processed_df = self.data_processor.preprocess_raw_data(raw_df)
            
            # 3. 缓存处理后的数据
            self.cache_manager.set_data_cache(processed_df)
            
            # 4. 获取数据摘要
            summary = self.data_processor.get_data_summary(processed_df)
            
            print("数据预加载完成")
            return {
                "status": "success",
                "message": "数据预加载完成",
                "summary": summary
            }
            
        except Exception as e:
            error_msg = f"预加载数据时出错: {e}"
            print(error_msg)
            return {
                "status": "error",
                "message": error_msg,
                "error": str(e)
            }
    
    def load_data(self, max_points=None, start_date=None, end_date=None):
        """
        加载数据的主要API函数
        
        Args:
            max_points: 最大数据点数量
            start_date: 开始日期
            end_date: 结束日期
        
        Returns:
            处理后的数据列表或错误信息
        """
        try:
            # 1. 生成缓存键
            cache_key = self.cache_manager.get_cache_key(max_points, start_date, end_date)
            
            # 2. 检查处理后数据的缓存
            cached_result = self.cache_manager.get_processed_cache(cache_key)
            if cached_result is not None:
                print(f"从缓存返回数据，键: {cache_key}")
                return cached_result
            
            # 3. 获取主数据缓存
            df = self.cache_manager.get_data_cache()
            
            # 4. 如果主缓存不存在或过期，重新加载
            if df is None:
                print("主缓存不存在或已过期，重新加载数据...")
                preload_result = self.preload_data()
                if preload_result["status"] == "error":
                    return {'error': preload_result["message"]}, 500
                df = self.cache_manager.get_data_cache()
            
            # 5. 处理数据
            result = self.data_processor.process_for_api(df, max_points, start_date, end_date)
            
            # 6. 缓存处理结果
            self.cache_manager.set_processed_cache(cache_key, result)
            
            print(f"返回 {len(result)} 条处理后的记录")
            return result
            
        except Exception as e:
            error_msg = f"加载数据时出错: {e}"
            print(error_msg)
            return {'error': error_msg}, 500
    
    def get_date_range(self):
        """
        获取数据日期范围的API函数
        
        Returns:
            包含min_date和max_date的字典或错误信息
        """
        try:
            # 1. 尝试从缓存获取数据
            df = self.cache_manager.get_data_cache()
            
            # 2. 如果缓存不可用，重新加载
            if df is None:
                print("缓存不可用，重新加载数据以获取日期范围...")
                preload_result = self.preload_data()
                if preload_result["status"] == "error":
                    return {'error': preload_result["message"]}, 500
                df = self.cache_manager.get_data_cache()
            
            # 3. 获取日期范围
            if 'StandardDate' in df.columns:
                min_date = df['StandardDate'].min()
                max_date = df['StandardDate'].max()
            else:
                # 如果没有StandardDate列，临时转换
                df_temp = df.copy()
                df_temp['StandardDate'] = df_temp['Date'].apply(
                    self.data_processor.convert_date_format
                )
                min_date = df_temp['StandardDate'].min()
                max_date = df_temp['StandardDate'].max()
            
            return {
                'min_date': min_date,
                'max_date': max_date
            }
            
        except Exception as e:
            error_msg = f"获取日期范围时出错: {e}"
            print(error_msg)
            return {'error': error_msg}, 500
    
    def reload_data(self):
        """
        强制重新加载数据
        
        Returns:
            dict: 操作结果
        """
        try:
            print("强制重新加载数据...")
            
            # 1. 清除缓存
            self.cache_manager.clear_cache()
            
            # 2. 重新预加载数据
            result = self.preload_data()
            
            return result
            
        except Exception as e:
            error_msg = f"重新加载数据时出错: {e}"
            print(error_msg)
            return {
                "status": "error",
                "message": error_msg,
                "error": str(e)
            }
    
    def get_data_info(self):
        """
        获取数据信息
        
        Returns:
            dict: 数据信息
        """
        try:
            # 获取缓存信息
            cache_info = self.cache_manager.get_cache_info()
            
            # 获取数据摘要
            df = self.cache_manager.get_data_cache()
            data_summary = None
            if df is not None:
                data_summary = self.data_processor.get_data_summary(df)
            
            return {
                "cache_info": cache_info,
                "data_summary": data_summary,
                "data_path": self.data_path,
                "file_exists": os.path.exists(self.data_path)
            }
            
        except Exception as e:
            return {
                "error": f"获取数据信息时出错: {str(e)}"
            }
    
    def validate_file_path(self, file_path):
        """
        验证文件路径
        
        Args:
            file_path: 文件路径
        
        Returns:
            tuple: (is_valid, message)
        """
        try:
            if not os.path.exists(file_path):
                return False, f"文件不存在: {file_path}"
            
            if not file_path.lower().endswith('.csv'):
                return False, "文件必须是CSV格式"
            
            # 尝试读取文件头部
            try:
                df_test = pd.read_csv(file_path, nrows=1)
                required_columns = ['Date', 'Time', 'Room_Occupancy_Count']
                missing_columns = [col for col in required_columns if col not in df_test.columns]
                
                if missing_columns:
                    return False, f"文件缺少必需的列: {missing_columns}"
                
            except Exception as e:
                return False, f"无法读取CSV文件: {str(e)}"
            
            return True, "文件验证通过"
            
        except Exception as e:
            return False, f"文件验证出错: {str(e)}"
    
    def change_data_source(self, new_data_path):
        """
        更改数据源
        
        Args:
            new_data_path: 新的数据文件路径
        
        Returns:
            dict: 操作结果
        """
        try:
            # 1. 验证新文件路径
            is_valid, message = self.validate_file_path(new_data_path)
            if not is_valid:
                return {
                    "status": "error",
                    "message": f"文件验证失败: {message}"
                }
            
            # 2. 更新数据路径
            old_path = self.data_path
            self.data_path = new_data_path
            
            # 3. 重新加载数据
            reload_result = self.reload_data()
            
            if reload_result["status"] == "success":
                return {
                    "status": "success",
                    "message": f"数据源已更改: {old_path} -> {new_data_path}",
                    "reload_result": reload_result
                }
            else:
                # 如果加载失败，恢复原路径
                self.data_path = old_path
                return {
                    "status": "error",
                    "message": f"加载新数据源失败，已恢复原路径: {reload_result['message']}"
                }
                
        except Exception as e:
            return {
                "status": "error",
                "message": f"更改数据源时出错: {str(e)}"
            } 